package com.xhsj.user.sms.purchase.service;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.collect.Lists;
import com.xhsj.user.hr.system.entity.TbGlobalUser;
import com.xhsj.user.hr.system.mapper.TbGlobalUserMapper;
import com.xhsj.user.hr.system.service.TbGlobalUserService;
import com.xhsj.user.sms.base.BaseService;
import com.xhsj.user.sms.process.mapper.TbPurchaseProcessHiTaskMapper;
import com.xhsj.user.sms.process.mapper.TbPurchaseProcessNodeMapper;
import com.xhsj.user.sms.process.mapper.TbPurchaseProcessOpinionMapper;
import com.xhsj.user.sms.process.service.TbPurchaseProcessTaskService;
import com.xhsj.user.sms.purchase.entity.*;
import com.xhsj.user.sms.purchase.vo.*;
import com.xhsj.user.sms.purchase.mapper.TbPurchaseApplyMapper;
import com.xhsj.user.sms.purchase.mapper.TbPurchaseOrderMapper;
import com.xhsj.user.sms.purchase.mapper.TbPurchaseOrderSubtaskMapper;
import com.xhsj.user.sms.purchase.mapper.TbPurchaseSubtaskReturnRecordMapper;
import com.xhsj.user.sms.purchase.query.FindRunTaskListQuery;
import com.xhsj.user.utils.IdGen;
import com.xhsj.user.utils.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.Serializable;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 采购申请表 服务实现类
 * </p>
 *
 * @author suxiaolin
 * @since 2020-04-13
 */
@Slf4j
@Service
@Transactional(rollbackFor = Exception.class)
//@CacheConfig(cacheNames = "TbPurchaseApply")
public class TbPurchaseApplyService extends BaseService<TbPurchaseApplyMapper, TbPurchaseApply> {
    @Autowired
    private TbPurchaseApplyMapper dao;
    @Autowired
    private TbGlobalUserService tbGlobalUserService;
    @Autowired
    private TbGlobalUserMapper tbGlobalUserMapper;

    @Autowired
    private TbPurchaseApplyFileService tbPurchaseApplyFileService;

    @Autowired
    private TbPurchaseApplyListService tbPurchaseApplyListService;

    @Autowired
    private TbPurchaseProcessHiTaskMapper tbPurchaseProcessHiTaskMapper;

    @Autowired
    private TbPurchaseProcessNodeMapper tbPurchaseProcessNodeMapper;

    @Autowired
    TbPurchaseProcessOpinionMapper tbPurchaseProcessOpinionMapper;

    @Autowired
    private TbPurchaseSubtaskPaymentApplyService tbPurchaseSubtaskPaymentApplyService;

    @Autowired
    private TbPurchaseSubtaskReturnRecordMapper tbPurchaseSubtaskReturnRecordMapper;

    @Autowired
    private TbPurchaseOrderMapper tbPurchaseOrderMapper;

    @Autowired
    private TbPurchaseOrderSubtaskMapper tbPurchaseOrderSubtaskMapper;


    @Override
    //@CacheEvict(cacheNames="TbPurchaseApply", allEntries=true)
    public boolean save(TbPurchaseApply entity) {
        return super.save(entity);
    }

    @Override
    //@Cacheable(key = "#id",sync = true)
    public TbPurchaseApply getById(Serializable id) {
        return super.getById(id);
    }

    @Override
    //@CacheEvict(cacheNames="TbPurchaseApply", allEntries=true)
    public boolean removeById(Serializable id) {
        return super.removeById(id);
    }

    //@CacheEvict(cacheNames="SysDict", allEntries=true)
    @Override
    public boolean removeByIds(Collection<? extends Serializable> idList) {
        return super.removeByIds(idList);
    }

    //@Cacheable(key = "#data",sync = true)
    public IPage<TbPurchaseApply> selectPage(Map<String, Object> data) {
        int currentPage = 1;
        if (!Objects.isNull(data.get("page"))) {
            currentPage = (Integer) data.get("page");
        }
        int pageSize = 20;
        if (!Objects.isNull(data.get("size"))) {
            pageSize = (Integer) data.get("size");
        }

        TbPurchaseApply entity = JSON.parseObject(JSON.toJSONString(data), TbPurchaseApply.class);
        Page<TbPurchaseApply> page = new Page(currentPage, pageSize);
        QueryWrapper<TbPurchaseApply> wrapper = new QueryWrapper(entity);
        return super.selectPage(page, wrapper);
    }

    @Override
    //@Cacheable(value = "TbPurchaseApply",sync = true)
    public List<TbPurchaseApply> selectAll() {
        return super.selectAll();
    }

    /**
     * 保存采购申请
     *
     * @author 苏小林
     * @date 2020/6/4 11:40
     * @param: data
     * @return: java.lang.Boolean
     */
    public Boolean savePurchaseApply(TbPurchaseApply data) throws Exception {
        if (StringUtils.isBlank(data.getPurchaseNumber())) {
            String applyNewNum = getApplyNewNum(data.getDeptId(), data.getCategory());
            if (StringUtils.isBlank(applyNewNum)) {
                throw new Exception("采购申请编号失败");
            }
            data.setPurchaseNumber(applyNewNum);
        }
        boolean save = super.save(data);
        if (save) {
            // 保存申请清单
            tbPurchaseApplyListService.removeApplyList(String.valueOf(data.getId()));
            List<TbPurchaseApplyList> tbPurchaseApplyList = data.getTbPurchaseApplyList();
            if (tbPurchaseApplyList.size() > 0) {
                for (TbPurchaseApplyList purchaseApplyList : tbPurchaseApplyList) {
                    purchaseApplyList.setId(IdGen.uuid());
                    purchaseApplyList.setCreateBy(data.getCreateBy());
                    purchaseApplyList.setUpdateBy(data.getCreateBy());
                    purchaseApplyList.setPurchaseApplyId(String.valueOf(data.getId()));
                }
                boolean b = tbPurchaseApplyListService.saveBatch(tbPurchaseApplyList);
                if (!b) {
                    throw new Exception("保存采购申请清单失败");
                }
            }

            //根据采购申请id删除采购申请意向或方案文件
            tbPurchaseApplyFileService.removeIntentionSchemeFile(String.valueOf(data.getId()));
            List<TbPurchaseApplyFile> tbPurchaseApplyIntentionSchemeFile = data.getTbPurchaseApplyFileList();
            if (tbPurchaseApplyIntentionSchemeFile != null && tbPurchaseApplyIntentionSchemeFile.size() > 0) {
                for (TbPurchaseApplyFile file : tbPurchaseApplyIntentionSchemeFile) {
                    file.setCreateBy(data.getCreateBy());
                    file.setId(IdGen.uuid());
                    file.setUpdateBy(data.getCreateBy());
                    file.setPurchaseApplyId(String.valueOf(data.getId()));
                }

                boolean b = tbPurchaseApplyFileService.saveBatch(tbPurchaseApplyIntentionSchemeFile);
                if (!b) {
                    throw new Exception("保存采购申请意向或方案文件失败");
                }
            }
        }
        return save;
    }

//    //开始流程
//    public boolean startProcess(TbPurchaseApply data) throws Exception {
//        //保存修改采购申请表
//        Boolean aBoolean = this.savePurchaseApply(data);
//        if (aBoolean) {
//            //流程
//            StartProcessDto startProcessDto = new StartProcessDto();
//            startProcessDto.setCreateBy(data.getCreateBy());
//            startProcessDto.setDataId(data.getId());
//            if (data.getSubmitStatus() == 2) {
//                // 查询领导
//                String leader = tbGlobalUserService.getLeaderByUserId(StringUtils.toLong(data.getCreateBy()));
//                startProcessDto.setUserId(leader);
//                String s = tbPurchaseProcessTaskService.startProcess(startProcessDto);
//                data.setNodeName(s);
//                if (dao.updateById(data) != 1) {
//                    throw new Exception("采购申请表保存节点失败");
//                }
//            }
//        }
//        return true;
//    }

    /**
     * 查询正在运行任务
     *
     * @author 苏小林
     * @date 2020/4/13 10:52
     * @param: findRunTaskListQuery
     * @return: com.baomidou.mybatisplus.core.metadata.IPage<com.xhsj.user.sms.purchase.vo.FindRunTaskListQueryVo>
     */
    public IPage<FindRunTaskListQueryVo> findRunTaskList(FindRunTaskListQuery findRunTaskListQuery) {

        Page<TbPurchaseApply> page = new Page(findRunTaskListQuery.getPage(), findRunTaskListQuery.getSize());

        // 查询角色列表
        List<String> roleList = tbGlobalUserService.getRoleListByUserId(Long.parseLong(findRunTaskListQuery.getUserId()));

        // 查询部门列表
        List<String> departList = tbGlobalUserMapper.getDepartIdsByUserId(Long.parseLong(findRunTaskListQuery.getUserId()));

        IPage<FindRunTaskListQueryVo> iPage = null;
        //采购申请审批
        if ("1".equals(findRunTaskListQuery.getType())) {
            iPage = dao.findRunTaskList(page, roleList, departList, findRunTaskListQuery);
        }

        //订单子任务审批
        if ("2".equals(findRunTaskListQuery.getType())) {
            iPage = dao.findRunOrderSubtaskTaskList(page, roleList, departList, findRunTaskListQuery);
        }

        return iPage;
    }

    /**
     * 查询历史任务
     *
     * @author 苏小林
     * @date 2020/4/13 15:29
     * @param: findRunTaskListQuery
     * @return: com.baomidou.mybatisplus.core.metadata.IPage<com.xhsj.user.sms.purchase.vo.FindRunTaskListQueryVo>
     */
    public IPage<FindHiTaskListVo> findHiTaskList(FindRunTaskListQuery findRunTaskListQuery) {
        Page<TbPurchaseApply> page = new Page(findRunTaskListQuery.getPage(), findRunTaskListQuery.getSize());

        String type = findRunTaskListQuery.getType();
        if ("1".equals(type)) {// 采购计划
            IPage<FindHiTaskListVo> iPage = dao.findHiTaskList(page, findRunTaskListQuery);
            return iPage;
        }else{
            IPage<FindHiTaskListVo> iPage = dao.findOrderHiTaskList(page,findRunTaskListQuery);
            return iPage;
        }


    }


    //进度通知
    public List<ProgressNoticeListQueryVo> progressNoticeList(String dataId) {
        return tbPurchaseProcessHiTaskMapper.progressNoticeList(dataId);
    }

    // 进度总览
    public List<ProgressOverviewListQueryVo> progressOverviewList(String processType, int category) {
        return tbPurchaseProcessNodeMapper.progressOverviewList(processType, category);
    }

    //流程进度
    public List<DepartmentTaskDetailsListQueryVo> subscriptionDetailsList(String purchaseApplyId) {
        return dao.subscriptionDetailsList(purchaseApplyId);

    }

    //审批记录
    public IPage<ApprovalRecordListQueryVo> approvalRecordList(String dataId, int processType, int pageNum, int pageSize) {
        Page<ApprovalRecordListQueryVo> selectPage = new Page(pageNum, pageSize);
        //审批记录采购申请
        IPage<ApprovalRecordListQueryVo> page = tbPurchaseProcessHiTaskMapper.approvalRecordList(selectPage, dataId, processType);
        List<ApprovalRecordListQueryVo> records = page.getRecords();
        for (ApprovalRecordListQueryVo record : records) {
            String userId = record.getUserId();
            if (StringUtils.isNotBlank(userId)) {
                TbGlobalUser user = tbGlobalUserService.getById(userId);
                record.setAuditor(user.getFullName());
            }

            String roleId = record.getRoleId();
            if (StringUtils.isNotBlank(roleId)) {
                List<TbGlobalUser> list = tbGlobalUserMapper.getUserListByRoleId(roleId);
                String collect = list.stream().map(tbGlobalUser -> tbGlobalUser.getFullName()).collect(Collectors.joining(","));
                record.setAuditor(collect);
            }

            String deptId = record.getDeptId();
            if (StringUtils.isNotBlank(deptId)) {
                List<TbGlobalUser> list = tbGlobalUserMapper.getUserListByDeptId(deptId);
                String collect = list.stream().map(tbGlobalUser -> tbGlobalUser.getFullName()).collect(Collectors.joining(","));
                record.setAuditor(collect);
            }
        }

        return page;
    }

    //部门审批页面流程进度
    public List<OpinionQueryVo> departmentProgressProgress(String nodeId, String dataId) {
        return tbPurchaseProcessOpinionMapper.departmentProgressProgress(nodeId, dataId);
    }

    //支付申请相关
    public List<Map<String, Object>> getOrderPaymentApplyData(String dataId, String purchaseApplyId) {
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.eq("purchase_order_id", dataId);
        queryWrapper.eq("purchase_apply_id", purchaseApplyId);
        queryWrapper.notIn("audit_status", 0);
        queryWrapper.select("id,purchase_apply_id AS purchaseApplyId,purchase_order_id AS purchaseOrderId," +
                "payment_money AS paymentMoney,batch,remarks,create_by AS paymentCreateBy");
        return tbPurchaseSubtaskPaymentApplyService.listMaps(queryWrapper);
    }

    public Map<String, Object> distributionDocumentsPage(String nodeId, String dataId, String purchaseApplyId) {
        Map<String, Object> departmentProgressProgress = new HashMap<>();
        //支付申请相关
        List<Map<String, Object>> orderPaymentApplyData = this.getOrderPaymentApplyData(dataId, purchaseApplyId);
        List<OpinionQueryVo> opinionQueryVos = tbPurchaseProcessOpinionMapper.departmentProgressProgress(nodeId, dataId);
        departmentProgressProgress.put("orderPaymentApplyData", orderPaymentApplyData);
        departmentProgressProgress.put("opinionQueryVos", opinionQueryVos);
        return departmentProgressProgress;
    }

    //获取上传支付凭证信息
    public List<Map<String, Object>> getPaymentVoucherData(String dataId, String nodeId, String purchaseApplyId) {
//        QueryWrapper queryWrapper=new QueryWrapper();
////        queryWrapper.select("");
////        queryWrapper.eq("","");
////        tbPurchaseOrderOtherFileService.listMaps();
        return null;
    }

    //获取申购详情列表
    public PurchaseApplyQueryVo getPurchaseApplyList(String purchaseApplyId) {
        return dao.getPurchaseApplyList(purchaseApplyId);
    }

    //供应链得成员
    public Set<Map<String, Object>> getMemberList(String deptName, List<String> roleKeynameList) {
        return tbGlobalUserMapper.getMemberList(deptName, roleKeynameList);
    }

    //物料不良记录
    public List<Map<String, Object>> getBadMaterialRecord(String dataId) {
        return tbPurchaseSubtaskReturnRecordMapper.getBadMaterialRecord(dataId);
    }


    //获取最新的采购申请编号
    public String getApplyNewNum(Integer deptId, String category) {
        String kinds = "A";
        String num = dao.getApplyNewNum(kinds);
        return getAutoNumUtils(deptId, category, num, kinds);
    }

    //获取最新的订单任务编号
    public String getOrderNewNum(Integer deptId, String category) {
        String kinds = "O";
        String num = tbPurchaseOrderMapper.getOrderNewNum(kinds);
        return getAutoNumUtils(deptId, category, num, kinds);
    }

    //获取最新的订单任务子任务编号
    public String getOrderSubtaskNewNum(Integer deptId, String category) {
        String kinds = "S";
        String num = tbPurchaseOrderSubtaskMapper.getOrderSubtaskNewNum(kinds);
        return getAutoNumUtils(deptId, category, num, kinds);
    }

    public String getAutoNumUtils(Integer deptId, String category, String num, String kinds) {
        String number = null;
        //日期
        Date date = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
        String time = sdf.format(date);
//        Object deptCode = redisTemplate.opsForValue().get("deptCode:"+deptId);
//        if(StringUtils.isNull(deptCode)){
//            return number;
//        }
        if ("1".equals(category)) {
            number = "xhsj" + time + "L" + kinds;
        } else if ("2".equals(category)) {
            number = "xhsj" + time + "F" + kinds;
        } else if ("3".equals(category)) {
            number = "xhsj" + time + "P" + kinds;
        } else if ("4".equals(category)) {
            number = "xhsj" + time + "M" + kinds;
        } else {
            return number;
        }
        int i = 1;
        if (StringUtils.isNotBlank(num)) {
//            String str1=num.substring(0, num.indexOf(kinds));
//            String s=num.substring(str1.length()+1, num.length());
            i = Integer.parseInt(num) + 1;
        }
        String s1 = StringUtils.addZeroForNum(String.valueOf(i), 2);
        return number + s1;
    }

    //通过id获取采购订单任务子任务
    public TbPurchaseOrderSubtask getPurchaseOrderSubtaskById(String id) {
        return tbPurchaseOrderSubtaskMapper.getPurchaseOrderSubtaskById(id);
    }

    public IPage<Map<String, Object>> findPurchaseList(Map<String, Object> data) {
        int currentPage = 1;
        if (!Objects.isNull(data.get("page"))) {
            currentPage = (Integer) data.get("page");
        }
        int pageSize = 20;
        if (!Objects.isNull(data.get("size"))) {
            pageSize = (Integer) data.get("size");
        }

        String type = String.valueOf(data.get("type")); // 1 采购申请 2 采购订单
        String userId = String.valueOf(data.get("userId"));
        if ("1".equals(type)) {// 采购申请
            IPage<TbPurchaseTask> page = new Page(currentPage, pageSize);
            IPage<Map<String, Object>> selectPage = dao.findPurchaseApply(page, userId);
            for (Map<String, Object> record : selectPage.getRecords()) {
                setUserList(record);
            }
            return selectPage;
        }

        if ("2".equals(type)) {// 采购订单
            IPage<TbPurchaseOrder> page = new Page(currentPage, pageSize);
            IPage<Map<String, Object>> selectPage = tbPurchaseOrderMapper.findPurchaseOrder(page, userId);
            for (Map<String, Object> record : selectPage.getRecords()) {
                setUserList(record);
            }
            return selectPage;
        }
        return null;
    }

    private void setUserList(Map<String, Object> record) {

        Map<String, String> map = dao.getTransferByDataId(String.valueOf(record.get("id")));
        if (map != null) {
            List<Object> list = Lists.newArrayList();
            list.add(map.get("dept_id"));
            list.add(map.get("user_id"));
            record.put("userList", list);
            record.put("transferId", map.get("id"));
        } else {
            List<Object> list = Lists.newArrayList();
            record.put("userList", list);
            record.put("transferId", "");
        }
    }

    public Integer getNodeNum(String dataId) {
        Integer integer = null;
        List<Integer> nodeNum = dao.getNodeNum(dataId);
        if (nodeNum != null && nodeNum.size() > 0) {
            Optional<Integer> max = nodeNum.stream().max(Comparator.comparingInt(Integer::shortValue));
            integer = max.get();
        }
        return integer;
    }
}
